var ace = require('brace'),
  Mock = require('mockjs');
require('brace/mode/javascript');
require('brace/mode/json');
require('brace/mode/xml');
require('brace/mode/html')
require('brace/theme/xcode');
require("brace/ext/language_tools.js");
var json5 = require('json5');
const MockExtra = require('common/mock-extra.js')

var langTools = ace.acequire("ace/ext/language_tools"),
  wordList = [
    // { name: '字符串', mock: '@string' },
    // { name: '自然数', mock: '@natural' },
    // { name: '浮点数', mock: '@float' },
    // { name: '字符', mock: '@character' },
    // { name: '布尔', mock: '@boolean' },
    // { name: 'url', mock: '@url' },
    // { name: '域名', mock: '@domain' },
    // { name: 'ip地址', mock: '@ip' },
    // { name: 'id', mock: '@id' },
    // { name: 'guid', mock: '@guid' },
    // { name: '当前时间', mock: '@now' },
    // { name: '时间戳', mock: '@timestamp'},
    // { name: '日期', mock: '@date' },
    // { name: '时间', mock: '@time' },
    // { name: '日期时间', mock: '@datetime' },
    // { name: '图片连接', mock: '@image' },
    // { name: '图片data', mock: "@imageData" },
    // { name: '颜色', mock: '@color' },
    // { name: '颜色hex', mock: '@hex' },
    // { name: '颜色rgba', mock: '@rgba' },
    // { name: '颜色rgb', mock: '@rgb' },
    // { name: '颜色hsl', mock: '@hsl' },
    // { name: '整数', mock: '@integer' },
    // { name: 'email', mock: '@email' },
    // { name: '大段文本', mock: '@paragraph' },
    // { name: '句子', mock: '@sentence' },
    // { name: '单词', mock: '@word' },
    // { name: '大段中文文本', mock: '@cparagraph' },
    // { name: '中文标题', mock: '@ctitle' },
    // { name: '标题', mock: '@title' },
    // { name: '姓名', mock: '@name' },
    // { name: '中文姓名', mock: '@cname' },
    // { name: '中文姓', mock: '@cfirst' },
    // { name: '中文名', mock: '@clast' },
    // { name: '英文姓', mock: '@first' },
    // { name: '英文名', mock: '@last' },
    // { name: '中文句子', mock: '@csentence' },
    // { name: '中文词组', mock: '@cword' },
    // { name: '地址', mock: '@region' },
    // { name: '省份', mock: '@province' },
    // { name: '城市', mock: '@city' },
    // { name: '地区', mock: '@county' },
    // { name: '转换为大写', mock: '@upper' },
    // { name: '转换为小写', mock: '@lower' },
    // { name: '挑选（枚举）', mock: '@pick' },
    // { name: '打乱数组', mock: '@shuffle' },
    // { name: '协议', mock: '@protocol' }
  ];

let dom = ace.acequire("ace/lib/dom");
ace.acequire("ace/commands/default_commands").commands.push({
  name: "Toggle Fullscreen",
  bindKey: "F9",
  exec: function(editor) {  
    if(editor._fullscreen_yapi){
      let fullScreen = dom.toggleCssClass(document.body, "fullScreen")
      dom.setCssClass(editor.container, "fullScreen", fullScreen)
      editor.setAutoScrollEditorIntoView(!fullScreen)
      editor.resize()
    }    
  }
})

function run(options) {
  var editor,
    mockEditor,
    rhymeCompleter;
  function handleJson(json) {
    var curData = mockEditor.curData;
    try {
      curData.text = json;
      var obj = json5.parse(json);
      curData.format = true;
      curData.jsonData = obj;
      curData.mockData = ()=>Mock.mock(MockExtra(obj, {})); //为防止时时 mock 导致页面卡死的问题，改成函数式需要用到再计算
    } catch (e) {
      curData.format = e.message;
    }
  }
  options = options || {};
  var container, data;
  container = options.container || 'mock-editor';
  if (options.wordList && typeof options.wordList === 'object' && options.wordList.name && options.wordList.mock) {
    wordList.push(options.wordList);
  }
  data = options.data || '';
  options.readOnly = options.readOnly || false;
  options.fullScreen = options.fullScreen || false;

  editor = ace.edit(container)
  editor.$blockScrolling = Infinity;
  editor.getSession().setMode('ace/mode/javascript');
  if (options.readOnly === true) {
    editor.setReadOnly(true);
    editor.renderer.$cursorLayer.element.style.display = "none";
  }
  editor.setTheme('ace/theme/xcode');
  editor.setOptions({
    enableBasicAutocompletion: true,
    enableSnippets: false,
    enableLiveAutocompletion: true,
    useWorker: true
  });
  editor._fullscreen_yapi = options.fullScreen;
  mockEditor = {
    curData: {},
    getValue: ()=>mockEditor.curData.text,
    setValue: function (data) {
        editor.setValue(handleData(data));
    },
    editor: editor,
    options: options,
    insertCode: (code)=>{
      let pos = editor.selection.getCursor()
      editor.session.insert(pos, code)
    }
  }

  function formatJson(json){
    try{
      return JSON.stringify(JSON.parse(json), null, 2);
    }catch(err){
      return json;
    }
  }

  function handleData(data){
    data = data || '';
    if(typeof data === 'string'){
      return formatJson(data);
    }else if (typeof data === 'object') {
      return JSON.stringify(data, null, "  ")
    }
  }

  rhymeCompleter = {
    identifierRegexps: [/[@]/],
    getCompletions: function (editor, session, pos, prefix, callback) {
      if (prefix.length === 0) {
        callback(null, []);
        return;
      }
      callback(null, wordList.map(function (ea) {
        return { name: ea.mock, value: ea.mock, score: ea.mock, meta: ea.name }
      }));
    }
  }

  langTools.addCompleter(rhymeCompleter);
  mockEditor.setValue(handleData(data));
  handleJson(editor.getValue())

  editor.clearSelection();

  editor.getSession().on('change', () => {
    handleJson(editor.getValue())
    if (typeof options.onChange === 'function') {
      options.onChange.call(mockEditor, mockEditor.curData);
    }
    editor.clearSelection();

  });

  return mockEditor;
}





/**
 * mockEditor({
      container: 'req_body_json', //dom的id
      data: that.state.req_body_json, //初始化数据
      onChange: function (d) {
        that.setState({
          req_body_json: d.text
        })
      }
    })
 */
module.exports = run;
